﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using Ionic.Zip;

namespace CRUpdater
{
    public partial class frmMain : Form
    {
        Thread thrMain;
        bool inProgress = false;
        Version version = new Version();
        string date;
        bool updateAvailable = false;

        public frmMain()
        {
            InitializeComponent();
        }

        private void Main_Shown(object sender, EventArgs e)
        {
            lblStatus.Text = "Closing Custom Recommended...";

            foreach (Process process in Process.GetProcesses())
            {
                if (process.ProcessName == "Custom Recommended.exe")
                {
                    process.Close();
                    while (!process.HasExited) { };
                    break;
                }
            }

            lblStatus.Text = "Checking for updates...";

            thrMain = new Thread(delegate() { CheckForUpdates(); });
            thrMain.Start();
            while (thrMain.ThreadState != System.Threading.ThreadState.Stopped) { Application.DoEvents(); };

            if (updateAvailable)
            {
                inProgress = true;
                lblStatus.Text = "Downloading update....";

                thrMain = new Thread(delegate() { DownloadUpdate(); });
                thrMain.Start();
                while (thrMain.ThreadState != System.Threading.ThreadState.Stopped) { Application.DoEvents(); };

                lblStatus.Text = "Extracting update...";

                thrMain = new Thread(delegate() { ExtractUpdate(); });
                thrMain.Start();
                while (thrMain.ThreadState != System.Threading.ThreadState.Stopped) { Application.DoEvents(); };

                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(Application.StartupPath + "\\crsettings.xml");
                xmlDoc.FirstChild.Attributes["version"].Value = version.ToString();
                xmlDoc.Save(Application.StartupPath + "\\crsettings.xml");
            }

            Process.Start(Application.StartupPath + "\\Custom Recommended.exe");
            Application.Exit();
        }

        private void CheckForUpdates()
        {
            XmlDocument xmlDoc = new XmlDocument();
            XmlNode xmlNode;
            xmlDoc.Load(Application.StartupPath + "\\crsettings.xml");
            xmlNode = xmlDoc.SelectSingleNode("/crsettings");

            try
            {
                WebClient wc = new WebClient();
                wc.DownloadFile(@"http://dl.dropbox.com/u/2683550/Heroes%20of%20Newerth/Custom%20Recommended/version.txt", Application.StartupPath + "\\version.txt");
                while (wc.IsBusy) { };
                wc.Dispose();
            }
            catch (WebException)
            {
                MessageBox.Show("Custom Recommended Items was unable to connect to the dropbox server to check for updates. Please verify your connection to 'http://www.dropbox.com/' try again.");
                return;
            }

            string[] versiontxt = File.ReadAllText(Application.StartupPath + "\\version.txt").Split('|');
            File.Delete(Application.StartupPath + "\\version.txt");
            date = versiontxt[1];

            if (versiontxt[0].StartsWith("@"))
            {
                if (new Version(versiontxt[0].Substring(1)) > new Version(Settings.strVersion))
                {
                    version = new Version(versiontxt[0].Substring(1));
                    updateAvailable = true;
                }
            }
            else
            {
                if (new Version(versiontxt[0]) > new Version(Settings.strVersion))
                {
                    version = new Version(versiontxt[0]);
                    updateAvailable = true;
                }
            }
        }

        private void DownloadUpdate()
        {
            WebClient wc = new WebClient();
            wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
            wc.DownloadFileAsync(new Uri(@"http://dl.dropbox.com/u/2683550/Heroes%20of%20Newerth/CustomRecommended.zip"), Application.StartupPath + "\\CustomRecommended.zip");

            while (wc.IsBusy) { };
        }

        private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            this.Invoke(new EventHandler(
                delegate
                {
                    int KBReceived = (int)e.BytesReceived / 1024;
                    int KBToReceive = (int)e.TotalBytesToReceive / 1024;
                    lblProgress.Text = "Downloaded " + KBReceived + " KB of " + KBToReceive + " KB";
                    lblPercent.Text = e.ProgressPercentage + "%";
                    progressBar.Value = e.ProgressPercentage;
                }));
        }

        private void ExtractUpdate()
        {
            using (ZipFile zip = ZipFile.Read(Application.StartupPath + "\\CustomRecommended.zip"))
            {
                foreach (ZipEntry entry in zip)
                {
                    if (entry.FileName != "crsettings.xml" && entry.FileName != "CRUpdater.exe" || !File.Exists(Application.StartupPath + "/" + entry.FileName))
                    {
                        entry.Extract(ExtractExistingFileAction.OverwriteSilently);
                    }
                }
            }

            File.Delete(Application.StartupPath + "\\CustomRecommended.zip");

            XmlDocument xmlDoc = new XmlDocument();
            XmlNode xmlNode;
            xmlDoc.Load(Application.StartupPath + "\\crsettings.xml");
            xmlNode = xmlDoc.SelectSingleNode("/crsettings");
            xmlNode.Attributes["version"].Value = version.ToString();
            xmlNode.Attributes["date"].Value = date;
            xmlDoc.Save(Application.StartupPath + "\\crsettings.xml");
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (inProgress)
            {
                if (MessageBox.Show(this, "Update is in progress, are you sure you wish to quit?", "CRUpdater", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    if (File.Exists(Application.StartupPath + "\\CustomRecommended.zip"))
                    {
                        try
                        {
                            File.Delete(Application.StartupPath + "\\CustomRecommended.zip");
                        }
                        catch (Exception) { }
                    }

                    Application.Exit();
                }
            }
            else
            {
                Application.Exit();
            }
        }
    }

    public static class Settings
    {
        public const string strVersion = "3.2.1";
    }
}
